/*
 * Copyright (C) 2013 tangzhi
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package org.tangzsoft.pdmviewer.storage.memory;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import org.tangzsoft.pdmviewer.model.PdmObject;
import org.tangzsoft.pdmviewer.model.PdmObjectRel.RelType;
import org.tangzsoft.pdmviewer.model.impl.PdmObjectImpl;
import org.tangzsoft.pdmviewer.storage.PdmObjectDAO;
import org.tangzsoft.pdmviewer.storage.spi.PdmObjectDAOSPI;
import org.tangzsoft.pdmviewer.storage.spi.StorageSPI;
import org.tangzsoft.pdmviewer.utils.Utils;


public class PdmObjectDAOSPIImpl implements PdmObjectDAOSPI {

    protected StorageSPI storage;
    
    
    /**
     * 对象表
     * 层次关系：文件ID - 对象类型(e.g. Table,Key,Column...) - 对象ID
     */
    private Map<String, Map<String, List<String>>> fileObjectIdx;
    
    /**
     * 对象属性表(分文件建表，提高查询速度)
     * 层次关系：文件ID - 对象ID - 对象属性Map
     */
    private Map<String, Map<String, Map<String, String>>> objectAttrs;
    
    PdmObjectDAOSPIImpl(MemoryStorageSPIImpl storage) {
        this.storage = storage;
        
        fileObjectIdx = new HashMap<String, Map<String, List<String>>>();
        objectAttrs = new HashMap<String, Map<String, Map<String, String>>>();
    }

    @Override
    public void create(String fileId, String name, String id, Map attrs) {
        
        // 记录对象表
        Map<String, List<String>> objectIdx;
        if (!fileObjectIdx.containsKey(fileId)) {
            objectIdx = new HashMap<String, List<String>>();
            fileObjectIdx.put(fileId, objectIdx);
        }else{
            objectIdx = fileObjectIdx.get(fileId);
        }
        
        List<String> idx;
        if (objectIdx.containsKey(name)) {
            idx = objectIdx.get(name);
        }else{
            idx = new ArrayList<String>();
            objectIdx.put(name, idx);
        }
        
        idx.add(id);
        
        // 记录对象属性表
        Map<String, Map<String, String>> oa;
        if (objectAttrs.containsKey(fileId)) {
            oa = objectAttrs.get(fileId);
        }else {
            oa = new HashMap<String, Map<String, String>>();
            objectAttrs.put(fileId, oa);
        }
        
        attrs.put("ObjectId", id);
        attrs.put("ObjectType", name);
        
        oa.put(id, attrs);
        
    }

    private PdmObject[] getPdmObjectByIds(String fileId, List<String> ids) {
        Map<String, Map<String, String>> oa = objectAttrs.get(fileId);
        List l = new ArrayList();
        
        for(String id : ids) {
            PdmObject obj = (PdmObject) Utils.map2Bean(oa.get(id), PdmObjectImpl.class);
            l.add( obj );
        }
        
        return (PdmObject[]) l.toArray(new PdmObject[l.size()]);
    }
    
    private PdmObject[] getPdmObjectByIds(String fileId, String[] ids) {
        Map<String, Map<String, String>> oa = objectAttrs.get(fileId);
        List l = new ArrayList();
        
        for(String id : ids) {
            PdmObject obj = (PdmObject) Utils.map2Bean(oa.get(id), PdmObjectImpl.class);
            l.add( obj );
        }
        
        return (PdmObject[]) l.toArray(new PdmObject[l.size()]);
    }
    
    @Override
    public PdmObject[] findDiagrams(String fileId) {
        
        Map<String, List<String>> objectIdx = fileObjectIdx.get(fileId);
        
        List<String> ids = objectIdx.get(PdmObject.OBJECT_TYPE_DIAGRAM);
        
        if (ids == null) { //TODO
            throw new UnsupportedOperationException("Not supported yet.");
        }
        
        return getPdmObjectByIds(fileId, ids);
    }

    @Override
    public PdmObject[] findTables(String fileId, String diagramId) {
        
        if (PdmObjectDAO.ALL_TABLES.equals(diagramId)) {
            List<String> tableIds = fileObjectIdx.get(fileId).get(PdmObject.OBJECT_TYPE_TABLE);
            return getPdmObjectByIds(fileId, tableIds);
        }else{
            //PdmObjectRel.RelType relType, String fileId, String parentId
            String[] tableIds = storage.getPdmObjectRelDAO().findChildren(fileId, RelType.DIAGRAM_TABLE, diagramId);
            return getPdmObjectByIds(fileId, tableIds);
        }
        
    }
    
}
